package com.ruoyi.web.controller.finance;

import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.finance.domain.WalmartPDFValidator;
import com.ruoyi.finance.domain.WalmartProfitReport;
import com.ruoyi.finance.domain.WalmartProfitReportDetail;
import com.ruoyi.finance.mapper.WalmartProfitReportDetailMapper;
import com.ruoyi.finance.mapper.WalmartProfitReportMapper;
import com.ruoyi.finance.service.WalmartProfitReportService;
import com.ruoyi.walmart.domain.shipments.vo.ShipmentMatchVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/finance/walmartProfitReport")
public class WalmartProfitReportController extends BaseController {

    @Value("${ruoyi.profile}")
    private String profilePath;

    @Autowired
    private WalmartProfitReportService walmartProfitReportService;

    @Autowired
    private WalmartProfitReportMapper walmartProfitReportMapper;

    @Autowired
    private WalmartProfitReportDetailMapper walmartProfitReportDetailMapper;

    /**
     * 查询walmart账单列表
     */
    @PreAuthorize("@ss.hasPermi('finance:walmartProfitReport:list')")
    @GetMapping("/selectWalmartProfitReportList")
    public TableDataInfo list(WalmartProfitReport walmartProfitReport)
    {
        startPage();
        List<WalmartProfitReport> list = walmartProfitReportService.selectPaymentMasterVotList(walmartProfitReport);
        return getDataTable(list);
    }

    /**
     * 上传walmart账单总报告
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartPaymentReport")
    public ResponseEntity<?> uploadWalmartPaymentReport(@RequestParam("csvFile") MultipartFile file,
                                                        @RequestParam("authId") Long authId,@RequestParam("rate") BigDecimal  rate) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseCSV(records,authId,getNickname(),rate);
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }

    /**
     * 上传walmart仓储费账单
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartStorageFeeReport")
    public ResponseEntity<?> uploadWalmartStorageFeeReport(@RequestParam("csvFile") MultipartFile file,
                                                        @RequestParam("wprId") Long wprId) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseStorageFeeCSV(records,wprId,getNickname());
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }

    /**
     * 上传walmart调整费账单
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartAdjustmentsReport")
    public ResponseEntity<?> uploadWalmartAdjustmentsReport(@RequestParam("csvFile") MultipartFile file,
                                                           @RequestParam("wprId") Long wprId) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseAdjustmentsCSV(records,wprId,getNickname());
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }

    /**
     * 上传walmart广告费账单
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartProductAdvertisingReport")
    public ResponseEntity<?> uploadWalmartProductAdvertisingReport(@RequestParam("csvFile") MultipartFile file,
                                                            @RequestParam("wprId") Long wprId) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseProductAdvertisingCSV(records,wprId,getNickname());
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }
    /**
     * 上传walmart 库存对账单(销售及调整数据)
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartInventoryLoadingReconciliationReport")
    public ResponseEntity<?> uploadWalmartInventoryLoadingReconciliationReport(@RequestParam("csvFile") MultipartFile file,
                                                                        @RequestParam("wprId") Long wprId) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseInventoryLoadingReconciliationCSV(records,wprId,getNickname());
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }
    /**
     * 上传walmart 库存对账单(期末数据)
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartInventoryReconciliationReport")
    public ResponseEntity<?> uploadWalmartInventoryReconciliationReport(@RequestParam("csvFile") MultipartFile file,
                                                                   @RequestParam("wprId") Long wprId) {
        Map<String, Object> errorResponse = new HashMap<>();
        try {
            // 1. 读取并解析 CSV
            List<String[]> records = parseCsv(file);
            walmartProfitReportService.parseInventoryReconciliationCSV(records,wprId,getNickname());
            errorResponse.put("success", true);

        } catch (Exception e) {
            // 同样使用HTTP 200但标记为操作失败
            errorResponse.put("success", false);
            errorResponse.put("error", "处理文件时发生错误：" + e.getMessage());
            return ResponseEntity.ok(errorResponse);
        }
        return ResponseEntity.ok(errorResponse);
    }

    /**
     * 上传walmart pdf账单
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartPdfReport")
    public AjaxResult uploadWalmartPdfReport(@RequestParam("csvFile") MultipartFile file,
                                             @RequestParam("wprId") Long wprId) {
        try {
            // 1. 获取配置路径（profilePath 是你配置文件中注入的变量）
            // 比如 profilePath = D:/baichenerpweb.com/baichenerpweb.com

            WalmartPDFValidator validator = new WalmartPDFValidator();
            // 2. 保存 PDF 文件
            String dbPathPDF = savePdfWithDate(file, profilePath);//savePdfWithDate(file, profilePath); // 保存后返回 /profile/upload/yyyy/MM/dd/xxx.pdf
            String dbPath= validator.savePdfWithDate(file, profilePath);

            // 3. 使用 OCR 提取 PDF 数据
            //WalmartPDFValidator validator = new WalmartPDFValidator();
            File pdfFile = new File(profilePath + dbPathPDF.replaceFirst("/profile", "")); // 拼成物理路径
            WalmartPDFValidator.PdfSummaryData pdfData = validator.extractFromPdfWithOCR(pdfFile); // 👈 用OCR读取

            // 4. 获取明细并汇总
            List<WalmartProfitReportDetail> detailList = walmartProfitReportDetailMapper.selectBatchProfitReportById(wprId);

            BigDecimal salesSum = detailList.stream()
                    .map(d -> Optional.ofNullable(d.getSalesProductPrice()).orElse(BigDecimal.ZERO)
                            .add(Optional.ofNullable(d.getSalesOtherTaxesFee()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getSalesCommissionSavings()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getSalesCommission()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getSalesFundedSavings()).orElse(BigDecimal.ZERO)))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal refundsSum = detailList.stream()
                    .map(d -> Optional.ofNullable(d.getRefundProductPrice()).orElse(BigDecimal.ZERO)
                            .add(Optional.ofNullable(d.getRefundCommission()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getRefundFundedSavings()).orElse(BigDecimal.ZERO)))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal wfsSum = detailList.stream()
                    .map(d -> Optional.ofNullable(d.getWfsFulfillmentFee()).orElse(BigDecimal.ZERO)
                            .add(Optional.ofNullable(d.getWfsReturnShippingFee()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getWfsStorageFee()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getWfsAdjustments()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getWfsInventoryTransferFee()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getWfsRcFee()).orElse(BigDecimal.ZERO))
                            .add(Optional.ofNullable(d.getWfsChargeFee()).orElse(BigDecimal.ZERO))
                    )
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal adSemSum = detailList.stream()
                    .map(d -> Optional.ofNullable(d.getProductAdvertising()).orElse(BigDecimal.ZERO)
                            .add(Optional.ofNullable(d.getSem()).orElse(BigDecimal.ZERO)))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            // 5. 校验 PDF 与数据库汇总值
            WalmartProfitReport report = walmartProfitReportMapper.selectById(wprId);
            report.setImagePath(dbPath);
            report.setStatus(Constants.WALMART_INVENTORY_RECONCILIATION_PENDING);
            walmartProfitReportMapper.updateById(report);

            validator.validateWithDatabase(report, pdfData, salesSum, refundsSum, wfsSum, adSemSum);

            return AjaxResult.success("✅ 文件上传并校验成功！");

        } catch (Exception e) {
            return AjaxResult.error("❌ 上传失败：" + e.getMessage());
        }
    }
    /**
     * walmart账单标记已库存对账
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartProfitReportInentrotyStatus/{wprId}")
    public ResponseEntity<String> uploadWalmartProfitReportInentrotyStatus(@PathVariable Long wprId) {

        if(wprId.equals("")){
            throw new ServiceException("获取账单ID失败");
        }
        WalmartProfitReport report = walmartProfitReportMapper.selectById(wprId);
        if(report == null){
            throw new ServiceException("获取账单失败");
        }
        report.setStatus(Constants.WALMART_NOT_PAID);
        walmartProfitReportMapper.updateById(report);
        // 返回响应
        return ResponseEntity.ok("状态更新成功");
    }
    /**
     * walmart账单标记已收款
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartProfitReportStatus')")
    @PostMapping("/uploadWalmartProfitReportStatus/{wprId}")
    public ResponseEntity<String> uploadWalmartProfitReportStatus(@PathVariable Long wprId) {

        if(wprId.equals("")){
            throw new ServiceException("获取账单ID失败");
        }
        WalmartProfitReport report = walmartProfitReportMapper.selectById(wprId);
        if(report == null){
            throw new ServiceException("获取账单失败");
        }
        report.setPaidStatus("1");
        walmartProfitReportMapper.updateById(report);
        // 返回响应
        return ResponseEntity.ok("状态更新成功");
    }
    /**
     * walmart匹配列表（成本、头程）
     */
    @PostMapping("/listShipmentMatch")
    public TableDataInfo listShipmentMatch(@RequestBody  ShipmentMatchVo shipmentMatch) {

        if(shipmentMatch.getWprId().equals("")){
            throw new ServiceException("获取账单ID失败");
        }
        List<ShipmentMatchVo> list = walmartProfitReportService.selectShipmentMatchVotList(shipmentMatch);
        return getDataTable(list);
    }
    /**
     * 更新关联货件配对表，匹配表，账单头程
     */
    @PostMapping("/updateShipmentStockFirstLeg/{stockId}")
    public ResponseEntity<String> updateShipmentStockFirstLeg(@PathVariable String stockId) {

        if(stockId.equals("")){
            throw new ServiceException("获取stockId失败");
        }
        walmartProfitReportService.updateShipmentStockFirstLeg(stockId);
        // 返回响应
        return ResponseEntity.ok("状态更新成功");
    }

    /**
     * 上传二次销售商品
     */
    @PreAuthorize("@ss.hasPermi('finance/walmartReport:uploadWalmartPaymentReport')")
    @PostMapping("/uploadWalmartShipmentStockAgain")
    public AjaxResult uploadWalmartShipmentStockAgain(@RequestParam("file") MultipartFile file,
                                                 @RequestParam("authId") Long authId) {
        try{
            walmartProfitReportService.uploadWalmartShipmentStockAgain(file,authId);
            return AjaxResult.success("✅ 文件上传并校验成功！");

        } catch (Exception e) {
            return AjaxResult.error("❌ 上传失败：" + e.getMessage());
        }
    }
    /**
     * 初始化数据
     */
    @PostMapping("/uploadInitData")
    public AjaxResult uploadInitData(@RequestParam("file") MultipartFile file) {
        try{
            walmartProfitReportService.uploadInitData(file);
            return AjaxResult.success("✅ 文件上传并校验成功！");

        } catch (Exception e) {
            return AjaxResult.error("❌ 上传失败：" + e.getMessage());
        }
    }


    private static String savePdfWithDate(MultipartFile file, String profilePath) throws IOException {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        String datePath = today.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));

        // 构建存储路径，按相对路径进行拼接
        String fullPath = profilePath + "/upload/" + datePath;

        // 创建目录，如果目录不存在则创建
        File dir = new File(fullPath);
        if (!dir.exists()) {
            dir.mkdirs(); // 创建目录
        }

        // 保存文件
        String fileName = file.getOriginalFilename();
        File destFile = new File(dir, fileName);

        // 将文件保存到指定目录
        file.transferTo(destFile);

        // 返回数据库存储的相对路径（供前端访问）
        String dbPath = "/profile/upload/" + datePath + "/" + fileName;

        // 返回数据库存储路径（相对路径）
        return dbPath;
    }
    //读取CSV
    private List<String[]> parseCsv(MultipartFile file) throws IOException {
        try (CSVReader reader = new CSVReaderBuilder(
                new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))
                .withCSVParser(new CSVParserBuilder()
                        .withSeparator(',')   // 默认是逗号分隔
                        .withQuoteChar('"')   // 正确处理带引号的字段
                        .build())
                .build()) {
            return reader.readAll();
        } catch (CsvException e) {
            throw new RuntimeException(e);
        }
    }
}
